<?php
/// ------------
/// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
/// ------------
/// | Copyright (c) 2006-2012 http:///thinkphp.cn All rights reserved.
/// ------------
/// | Licensed ( http:///www.apache.org/licenses/LICENSE-2.0 )
/// ------------
/// | Author: liu21st <liu21st@gmail.com>
/// ------------
/// $Id: Action.class.php 2945 2012-05-12 10:28:47Z liu21st@gmail.com $

/**
 * ThinkPHP Action控制器基类 抽象类
 * @category   Think
 * @package  Think
 * @subpackage  Core
 * @author   liu21st <liu21st@gmail.com>
 * @version  $Id: Action.class.php 2945 2012-05-12 10:28:47Z liu21st@gmail.com $
 */
abstract class Action {

    /// 视图实例对象
    protected $view   =  null;
    /// 当前Action名称
    private $name =  '';
    ///当前TPL的页面名称
    public $tplName	=	''; 
    private $_trans = false;
    
    protected $add_log = false;
    

    
   /**
     * 架构函数 取得模板对象实例
     * @access public
     */
    public function __construct() {
    	 /// 判断操作是否需要开启事务
        if (in_array(ACTION_NAME,C('TRANS_ACTION'))) {
        	$this->_trans = true;
        }
        $this->_trans == true && startTrans();
        tag('action_begin');
        ///实例化视图类
        $this->view       = Think::instance('View');
        ///控制器初始化
        if(method_exists($this,'_initialize'))
            $this->_initialize();
       
    }
    
    public function setName($name){
    	$this->name	=	$name;
    }

   /**
     * 获取当前Action名称
     * @access protected
     */
    protected function getActionName($suffix='') {
        if(empty($this->name)) {
            /// 获取Action名称 
///            $this->name     =   substr(get_class($this),0,-6);
            $this->name     =   MODULE_NAME;
        }
        return $this->name.$suffix;
    }
    
    
    /**
     * 获取当前Action名称对应的Model模块
     * @access protected
     */
    protected function getModel($suffix=''){ 
		///获取当前Action名称
		$name = $this->getActionName($suffix);
 		///获取当前模型 
    	return $model 	= D($name);    
    }

    /**
     * 是否AJAX请求
     * @access protected
     * @return bool
     */
    protected function isAjax() {
        if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {
            if('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH']))
                return true;
        }
        if(!empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')]))
            /// 判断Ajax方式提交
            return true;
        return false;
    }

    /**
     * 模板显示
     * 调用内置的模板引擎显示方法，
     * @access protected
     * @param string $templateFile 指定要调用的模板文件
     * 默认为空 由系统自动定位模板文件
     * @param string $charset 输出编码
     * @param string $contentType 	输出类型
     * @param string $strShow 		返回显示的内容
     * @return void
     */
    protected function display($templateFile='',$charset='',$contentType='',$strShow=false) {
		return $this->view->display($templateFile,$charset,$contentType,$strShow);
    }

    /**
     * 输出内容文本可以包括Html
     * @access protected
     * @param string $content 输出内容
     * @param string $charset 模板输出字符集
     * @param string $contentType 输出类型
     * @return mixed
     */
    protected function show($content,$charset='',$contentType='') {
    	if (empty($content)) {
    		echo $this->fetch();
    	}
        return $this->view->show($content,$charset,$contentType);
    }

    /**
     *  获取输出页面内容
     * 调用内置的模板引擎fetch方法，
     * @access protected
     * @param string $templateFile 指定要调用的模板文件
     * 默认为空 由系统自动定位模板文件
     * @return string
     */
    protected function fetch($templateFile='') {
        return $this->view->fetch($templateFile);
    }

    /**
     *  创建静态页面
     * @access protected
     * @htmlfile 生成的静态文件名称
     * @htmlpath 生成的静态文件路径
     * @param string $templateFile 指定要调用的模板文件
     * 默认为空 由系统自动定位模板文件
     * @return string
     */
    protected function buildHtml($htmlfile='',$htmlpath='',$templateFile='') {
        $content = $this->fetch($templateFile);
        $htmlpath   = !empty($htmlpath)?$htmlpath:HTML_PATH;
        $htmlfile =  $htmlpath.$htmlfile.C('HTML_FILE_SUFFIX');
        if(!is_dir(dirname($htmlfile)))
            /// 如果静态目录不存在 则创建
            mkdir(dirname($htmlfile),0777,true);
        if(false === file_put_contents($htmlfile,$content))
            throw_exception(L('_CACHE_WRITE_ERROR_').':'.$htmlfile);
        return $content;
    }

    /**
     * 模板变量赋值
     * @access protected
     * @param mixed $name 要显示的模板变量
     * @param mixed $value 变量的值
     * @return void
     */
    protected function assign($name,$value='') {
        $this->view->assign($name,$value);
    }

    public function __set($name,$value) {
        $this->view->assign($name,$value);
    }

    /**
     * 取得模板显示变量的值
     * @access protected
     * @param string $name 模板显示变量
     * @return mixed
     */
    public function __get($name) {
        return $this->view->get($name);
    }

    /**
     * 魔术方法 有不存在的操作的时候执行
     * @access public
     * @param string $method 方法名
     * @param array $args 参数
     * @return mixed
     */
    public function __call($method,$args) { 
        if( 0 === strcasecmp($method,ACTION_NAME)) { 
            if(method_exists($this,'_empty')) {
                /// 如果定义了_empty操作 则调用
                $this->_empty($method,$args);
            }elseif(file_exists_case(C('TEMPLATE_NAME')) || file_exists_case(str_replace(APP_PATH,THINK_PATH,C('TEMPLATE_NAME')))){
                /// 检查是否存在默认模版 如果有直接输出模版
                $this->display();
            }elseif(function_exists('__hack_action')) {
                /// hack 方式定义扩展操作
                __hack_action(); 
            }elseif (substr($method,0,5)=='alist'){ 
            	 $this->_autoIndex($method,$args);
            }else{
                _404(L('_ERROR_ACTION_').':'.ACTION_NAME);
            }
        }else{
            switch(strtolower($method)) {
                /// 判断提交方式
                case 'ispost':
                case 'isget':
                case 'ishead':
                case 'isdelete':
                case 'isput':
                    return strtolower($_SERVER['REQUEST_METHOD']) == strtolower(substr($method,2));
                /// 获取变量 支持过滤和默认值 调用方式 $this->_post($key,$filter,$default);
                case '_get':      $input =& $_GET;break;
                case '_post':$input =& $_POST;break;
                case '_put': parse_str(file_get_contents('php:///input'), $input);break;
                case '_param':  
                    switch($_SERVER['REQUEST_METHOD']) {
                        case 'POST':
                            $input    =  $_POST;
                            break;
                        case 'PUT':
                            parse_str(file_get_contents('php:///input'), $input);
                            break;
                        default:
                            $input  =  $_GET;
                    }
                    if(C('VAR_URL_PARAMS')){
                        $params = $_GET[C('VAR_URL_PARAMS')];
                        $input  =   array_merge($input,$params);
                    }
                    break;
                case '_request': $input =& $_REQUEST;break;
                case '_session': $input =& $_SESSION;break;
                case '_cookie':  $input =& $_COOKIE;break;
                case '_server':  $input =& $_SERVER;break;
                case '_globals':  $input =& $GLOBALS;break;
                default:
                    throw_exception(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
            }
            if(isset($input[$args[0]])) { /// 取值操作
                $data	 =	 $input[$args[0]];
                $filters  =  isset($args[1])?$args[1]:C('DEFAULT_FILTER');
                if($filters) {/// 2012/3/23 增加多方法过滤支持
                    $filters    =   explode(',',$filters);
                    foreach($filters as $filter){
                        if(function_exists($filter)) {
                            $data   =   is_array($data)?array_map($filter,$data):$filter($data); /// 参数过滤
                        }
                    }
                }
            }else{ /// 变量默认值
                $data	 =	 isset($args[2])?$args[2]:NULL;
            }
            return $data;
        }
    }

    /**
     * 操作错误跳转的快捷方法
     * @access protected
     * @param string $message 错误信息
     * @param string $jumpUrl 页面跳转地址
     * @param Boolean $ajax 是否为Ajax方式
     * @return void
     */
    protected function error($message,$status=0,$jumpUrl='',$ajax=false) {
        $this->dispatchJump($message,$status,$jumpUrl,$ajax);
    }

    /**
     * 操作成功跳转的快捷方法
     * @access protected
     * @param string $message 提示信息
     * @param string $jumpUrl 页面跳转地址
     * @param Boolean $ajax 是否为Ajax方式
     * @return void
     */
    protected function success($message,$jumpUrl='',$ajax=false) {
    	($_POST['submit_type']==1) && $ajax = array('status'=>1,'href'=>U(MODULE_NAME.'/index'),'title'=>title('index',MODULE_NAME));
    	$this->add_log = true;
        $this->dispatchJump($message,1,$jumpUrl,$ajax);
    }

    /**
     * Ajax方式返回数据到客户端
     * @access protected
     * @param mixed $data 要返回的数据
     * @param String $info 提示信息
     * @param boolean $status 返回状态
     * @param String $status ajax返回类型 JSON XML
     * @return void
     */
    protected function ajaxReturn($data,$info='',$status=1,$type='') {
        $result  =  array();
        $result['status']  	= $status;
        $result['info'] 	= $info;
        $result['id'] 		= $this->id;
        isset($_POST['comp_name']) && $result['comp_name'] = $_POST['comp_name'];
        isset($_POST['color_name']) && $result['color_name'] = $_POST['color_name'];
        isset($_POST['size_name']) && $result['size_name'] = $_POST['size_name'];
        isset($_POST['position_name']) && $result['position_name'] = $_POST['position_name'];
        isset($_POST['department_name']) && $result['department_name'] = $_POST['department_name'];
        isset($_POST['employee_name']) && $result['employee_name'] = $_POST['employee_name'];
        isset($_POST['product_no']) && $result['product_no'] = $_POST['product_no'];
        isset($_POST['factory_id']) && $result['factory_id'] = $_POST['factory_id'];
        isset($_POST['pay_class_name']) && $result['pay_class_name'] = $_POST['pay_class_name'];
        $result['product_factory'] = C('product_factory');
        $result['data'] 	= $data;
        ///扩展ajax返回数据, 在Action中定义function ajaxAssign(&$result){} 方法 扩展ajax返回数据。
        if(method_exists($this,'ajaxAssign')) 
            $this->ajaxAssign($result);
        if(empty($type)) $type  =   C('DEFAULT_AJAX_RETURN');
        if(strtoupper($type)=='JSON') {
            /// 返回JSON数据格式到客户端 包含状态信息
            header('Content-Type:text/html; charset=utf-8');
            exit(json_encode($result));
        }elseif(strtoupper($type)=='XML'){
            /// 返回xml格式数据
            header('Content-Type:text/xml; charset=utf-8');
            exit(xml_encode($result));
        }elseif(strtoupper($type)=='EVAL'){
            /// 返回可执行的js脚本
            header('Content-Type:text/html; charset=utf-8');
            exit($data);
        }else{
            /// TODO 增加其它格式
        }
    }

    /**
     * Action跳转(URL重定向） 支持指定模块和延时跳转
     * @access protected
     * @param string $url 跳转的URL表达式
     * @param array $params 其它URL参数
     * @param integer $delay 延时跳转的时间 单位为秒
     * @param string $msg 跳转提示信息
     * @return void
     */
    protected function redirect($url,$params=array(),$delay=0,$msg='') {
        $url    =   U($url,$params);
        redirect($url,$delay,$msg);
    }

    /**
     * 默认跳转操作 支持错误导向和正确跳转
     * 调用模板显示 默认为public目录下面的success页面
     * 提示页面为可配置 支持模板标签
     * @param string $message 提示信息
     * @param Boolean $status 状态   0失败  1成功  2   请求成功表单验证失败
     * @param string $jumpUrl 页面跳转地址
     * @param Boolean $ajax 是否为Ajax方式
     * @access private
     * @return void
     */
    private function dispatchJump($message,$status=1,$jumpUrl='',$ajax=false) {
        /// 判断是否为AJAX返回
        if($ajax || $this->isAjax()) $this->ajaxReturn($ajax,$message,$status);
        if(!empty($jumpUrl)) $this->assign('jumpUrl',$jumpUrl);
        /// 提示标题
        $this->assign('msgTitle',$status? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_'));
        ///如果设置了关闭窗口，则提示完毕后自动关闭窗口
        if($this->view->get('closeWin'))    $this->assign('jumpUrl','javascript:window.close();');
        $this->assign('status',$status);   /// 状态
        ///保证输出不受静态缓存影响
        C('HTML_CACHE_ON',false);
        if($status) { ///发送成功信息
            $this->assign('message',$message);/// 提示信息
            /// 成功操作后默认停留1秒
            if(!$this->view->get('waitSecond'))    $this->assign('waitSecond','1');
            /// 默认操作成功自动返回操作前页面
            if(!$this->view->get('jumpUrl')) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]);
            $this->display(C('TMPL_ACTION_SUCCESS'));
        }else{
            $this->assign('error',$message);/// 提示信息
            ///发生错误时候默认停留3秒
            if(!$this->view->get('waitSecond'))    $this->assign('waitSecond','3');
            /// 默认发生错误的话自动返回上页
            if(!$this->view->get('jumpUrl')) $this->assign('jumpUrl',"javascript:history.back(-1);");
            $this->display(C('TMPL_ACTION_ERROR'));
            /// 中止执行  避免出错后继续执行
            exit ;
        }
    }

   /**
     * 析构方法
     * @access public
     */
    public function __destruct() {
        /// 保存日志
        if(C('LOG_RECORD')) Log::save();
        /// 执行后续操作
        $ary = array();
        if ($this->add_log===true) {
        	$ary = array('id'=>$this->id);
        	tag('action_end',$ary);
        }
        $this->_trans == true && commit();
    }
    
    ///自动编号补充
	public function _autoMaxNo($step=1,$model=null){   
			if (C(strtoupper($this->_setauto_cache))==1){
				if (ACTION_NAME=='add' || MODULE_NAME=='QuicklyOperate'){ 
					///获取当前Action名称
					if(MODULE_NAME=='QuicklyOperate')
						$name = ACTION_NAME;
					else 
						$name = $this->getActionName();
			 		///获取当前模型
					$model 	= D($name);    
					///获取最大编号NO
					if ($this->_default_where){ 
						$max_no	=	intval($model->where($this->_default_where)->order($this->_auto_no_name.' desc')->getField($this->_auto_no_name))+$step;  
					}else{
						$max_no	=	intval($model->order($this->_auto_no_name.' desc')->getField($this->_auto_no_name))+$step;  
					}    
					$leng	=	$this->_setauto_leng>0?$this->_setauto_leng:3;
					///判断是否开启条形码
					if (C('barcode')==1){ 
						///需要根据条形码生成长度
						$check_leng_array	=	array(
														'setauto_color_no'			=>getBarcodeLen('color_no'),
														'setauto_productclass_no'	=>getBarcodeLen('class_no'),
														'setauto_product_no'		=>getBarcodeLen('product_no'),
														'setauto_factory_no'		=>getBarcodeLen('comp_no'),
														'setauto_size_no'			=>getBarcodeLen('size_no'),
						);    
						///判断KEY是否在条形码设置的长度当中.
						if (in_array($this->_setauto_cache,array_keys($check_leng_array)) && $check_leng_array[$this->_setauto_cache]>0){
							$leng	=	$check_leng_array[$this->_setauto_cache];
						} 
					}
					$max_no	=	str_pad($max_no,$leng,'0',STR_PAD_LEFT); 
					$this->assign ( 'max_no',$max_no);
				}   
				$is_auto_no_class	=	' readonly class="spc_input disabled" ';
				$this->assign ( 'is_auto_no',$is_auto_no_class);	
			}
			else {
				$is_auto_no_class	=	' class="spc_input" ';
				$this->assign ( 'is_auto_no',$is_auto_no_class);	
			} 
		
	}
		
	///列表显示
	public function displayIndex($temp_file=null) {  
		 
		if ($_POST['search_form']) { 
			$temp_file	=	empty($this->tplName)?'list':$this->tplName;
			$this->display ($this->_Member.$temp_file);
		}else { 
			$temp_file	=	empty($temp_file)?ACTION_NAME:$temp_file;  
			$this->display($this->_Member.$temp_file);
		} 
	} 
	
	
}